﻿using AuSys.Services.App.ActionFilters;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;

namespace AuSys.Utils.Reflection
{
    public static class ApiActionReader
    {
        public static HashSet<string> GetUserAccessScope(
            object controller, HttpContext context)
        {
            string actionName = context
                .GetRouteValue("action") as string
                ?? throw new Exception("Action特性读取：RouteValue异常");
            var ctype = controller.GetType();
            var scopesInController = ctype.GetCustomAttributes<UserAccessScopeAttribute>();

            var action = ctype.FindMembers(
                MemberTypes.Method,
                BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance,
                (x, o) =>
                {
                    var actionNameAttr = x.GetCustomAttribute<ActionNameAttribute>();
                    if (actionNameAttr is { } && string.Equals(actionNameAttr.Name, actionName, StringComparison.OrdinalIgnoreCase))
                        return true;
                    if (string.Equals(x.Name, actionName, StringComparison.OrdinalIgnoreCase))
                        return true;
                    return false;
                },null)
                .FirstOrDefault();
            var scopesInAction = action?.GetCustomAttributes<UserAccessScopeAttribute>();
            HashSet<string> res = [];
            foreach(var scope in scopesInController)
            {
                if(!scope.Reverse)
                    res.Add(scope.Name.ToLower());
            }
            if (scopesInAction is not null)
            {
                foreach (var scope in scopesInAction)
                {
                    if(scope.Reverse)
                        res.Remove(scope.Name.ToLower());
                    else
                        res.Add(scope.Name.ToLower());
                }
            }
            return res;
        }
    }
}
